const express = require('express');
const Imap = require('imap');
const { simpleParser } = require('mailparser');
const axios = require('axios');
const path = require('path');
const fs = require('fs');

// 配置密码
const ADMIN_PASSWORD = '@Tianqibucuo';

// 配置发送邮件
const SEND_MAIL_URL = 'http://150.5.163.98:22489/mail_sys/send_mail_http.json';
// 数据文件路径
const DATA_DIR = path.join(__dirname, '../data');
const WECHAT_CONFIG_FILE = path.join(DATA_DIR, 'wechat-config.json');
const WATCHERS_CONFIG_FILE = path.join(DATA_DIR, 'watchers-config.json');

// 确保数据目录存在
if (!fs.existsSync(DATA_DIR)) {
    fs.mkdirSync(DATA_DIR, { recursive: true });
}

// 简单的session存储（生产环境建议使用Redis等）
const sessions = new Map();

// 生成随机session ID
function generateSessionId() {
    return Math.random().toString(36).substring(2) + Date.now().toString(36);
}

// 身份验证中间件
function requireAuth(req, res, next) {
    const sessionId = req.headers['x-session-id'];

    if (sessionId && sessions.has(sessionId)) {
        const session = sessions.get(sessionId);
        if (session.expires > Date.now()) {
            // 延长session有效期
            session.expires = Date.now() + 24 * 60 * 60 * 1000; // 24小时
            return next();
        } else {
            sessions.delete(sessionId);
        }
    }

    return res.status(401).json({ error: 'Unauthorized', needLogin: true });
}

// 数据持久化函数
function saveWeChatConfig(config) {
    try {
        fs.writeFileSync(WECHAT_CONFIG_FILE, JSON.stringify(config, null, 2));
        console.log('WeChat config saved to file');
    } catch (error) {
        console.error('Failed to save WeChat config:', error);
    }
}

function loadWeChatConfig() {
    try {
        if (fs.existsSync(WECHAT_CONFIG_FILE)) {
            const data = fs.readFileSync(WECHAT_CONFIG_FILE, 'utf8');
            return JSON.parse(data);
        }
    } catch (error) {
        console.error('Failed to load WeChat config:', error);
    }
    return { webhookKey: '' };
}

function saveWatchersConfig() {
    try {
        const watchersData = {};
        Object.keys(watchers).forEach(email => {
            watchersData[email] = {
                email,
                callback: watchers[email].callback,
                host: watchers[email].host,
                port: watchers[email].port,
                tls: watchers[email].tls,
                autoReply: watchers[email].autoReply || {
                    enabled: false,
                    subjectPrefix: 'Re: ',
                    textContent: '感谢您的邮件，我已收到并会尽快回复。',
                    htmlContent: ''
                }
                // 不保存敏感信息如密码和 imap 连接对象
            };
        });
        fs.writeFileSync(WATCHERS_CONFIG_FILE, JSON.stringify(watchersData, null, 2));
        console.log('Watchers config saved to file');
    } catch (error) {
        console.error('Failed to save watchers config:', error);
    }
}

function loadWatchersConfig() {
    try {
        if (fs.existsSync(WATCHERS_CONFIG_FILE)) {
            const data = fs.readFileSync(WATCHERS_CONFIG_FILE, 'utf8');
            return JSON.parse(data);
        }
    } catch (error) {
        console.error('Failed to load watchers config:', error);
    }
    return {};
}

// 辅助函数：从HTML中提取链接
function extractLinks(html) {
    if (!html) return [];
    const linkRegex = /<a[^>]+href=["']([^"']+)["'][^>]*>([^<]*)<\/a>/gi;
    const links = [];
    let match;

    while ((match = linkRegex.exec(html)) !== null) {
        links.push({
            url: match[1],
            text: match[2].trim()
        });
    }

    return links;
}

// 发送企业微信消息
async function sendToWeChat(webhookKey, subject, from, to) {
    if (!webhookKey) {
        console.log('No WeChat webhook key configured, skipping notification');
        return;
    }

    const url = `https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${webhookKey}`;
    const message = {
        msgtype: "text",
        text: {
            content: `📧 新邮件通知\n\n📋 主题: ${subject}\n📤 发送邮箱: ${from}\n📥 接收邮箱: ${to}\n\n⏰ 时间: ${new Date().toLocaleString('zh-CN')}`
        }
    };

    try {
        await axios.post(url, message);
        console.log('WeChat notification sent successfully');
    } catch (error) {
        console.error('Failed to send WeChat notification:', error.message);
    }
}

// 发送自动回复邮件
async function sendAutoReply(emailAccount, password, host, port, tls, replyConfig, originalMessage) {
    if (!replyConfig || !replyConfig.enabled) {
        console.log(`[${emailAccount}] Auto reply is disabled`);
        return { success: true, skipped: true };
    }

    try {
        // 构建回复邮件内容
        const replySubject = (replyConfig.subjectPrefix || 'Re: ') + (originalMessage.subject || '');
        const replyTo = originalMessage.from;
        const content = replyConfig.htmlContent || replyConfig.textContent || '感谢您的邮件，我已收到并会尽快回复。';

        // 准备发送邮件的数据
        const mailData = {
            mail_from: emailAccount,
            password: password,
            mail_to: replyTo,
            subject: replySubject,
            content: content,
            subtype: replyConfig.htmlContent ? "html" : ""
        };

        console.log(`[${emailAccount}] Sending auto reply to ${replyTo} via external API...`);

        // 发送邮件到外部API
        const response = await axios.post(SEND_MAIL_URL, mailData, {
            headers: {
                'Content-Type': 'application/json'
            },
            timeout: 30000 // 30秒超时
        });

        if (response.status === 200) {
            console.log(`[${emailAccount}] Auto reply sent successfully to ${replyTo}`);
            return { success: true, response: response.data };
        } else {
            console.error(`[${emailAccount}] Auto reply failed with status: ${response.status}`);
            return { success: false, error: `HTTP ${response.status}` };
        }

    } catch (error) {
        console.error(`[${emailAccount}] Failed to send auto reply:`, error.message);
        return { success: false, error: error.message };
    }
}

const app = express();
app.use(express.json());

// 服务静态文件
app.use(express.static(path.join(__dirname, '../public')));

// 保存当前正在监听的邮箱: key 是邮箱账号
const watchers = {};
// 监听器状态跟踪
const watcherStatus = {};

// 更新监听器状态
function updateWatcherStatus(email, status, message = '') {
    watcherStatus[email] = {
        status, // 'connecting', 'connected', 'error', 'disconnected'
        message,
        lastUpdate: new Date().toISOString()
    };
}

// 企业微信配置 - 从文件加载
let wechatConfig = loadWeChatConfig();
console.log('Loaded WeChat config:', wechatConfig.webhookKey ? 'Key configured' : 'No key configured');

// 加载已保存的监听器配置（仅用于显示，不自动重启监听）
const savedWatchersConfig = loadWatchersConfig();
console.log('Loaded saved watchers:', Object.keys(savedWatchersConfig));

// 登录接口
app.post('/api/login', (req, res) => {
    const { password } = req.body;

    if (password === ADMIN_PASSWORD) {
        const sessionId = generateSessionId();
        sessions.set(sessionId, {
            expires: Date.now() + 24 * 60 * 60 * 1000 // 24小时
        });

        res.json({
            success: true,
            sessionId,
            message: 'Login successful'
        });
    } else {
        res.status(401).json({
            success: false,
            message: 'Invalid password'
        });
    }
});

// 登出接口
app.post('/api/logout', (req, res) => {
    const sessionId = req.headers['x-session-id'];
    if (sessionId && sessions.has(sessionId)) {
        sessions.delete(sessionId);
    }
    res.json({ success: true, message: 'Logged out successfully' });
});

// 验证session接口
app.get('/api/verify', requireAuth, (req, res) => {
    res.json({ success: true, message: 'Session valid' });
});

// 主页路由 - 需要身份验证
app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, '../public/index.html'));
});

// 获取所有监听的邮箱 - 需要身份验证
app.get('/api/watchers', requireAuth, (req, res) => {
    // 合并当前活跃的监听器和已保存的配置
    const activeWatchers = Object.keys(watchers).map(email => ({
        email,
        callback: watchers[email].callback,
        host: watchers[email].host,
        port: watchers[email].port,
        tls: watchers[email].tls,
        autoReply: watchers[email].autoReply || {
            enabled: false,
            subjectPrefix: 'Re: ',
            textContent: '感谢您的邮件，我已收到并会尽快回复。',
            htmlContent: ''
        },
        status: 'active',
        connectionStatus: watcherStatus[email] || { status: 'unknown', message: '', lastUpdate: '' }
    }));

    // 添加已保存但未活跃的监听器配置
    const savedWatchers = Object.keys(savedWatchersConfig)
        .filter(email => !watchers[email])
        .map(email => ({
            ...savedWatchersConfig[email],
            autoReply: savedWatchersConfig[email].autoReply || {
                enabled: false,
                subjectPrefix: 'Re: ',
                textContent: '感谢您的邮件，我已收到并会尽快回复。',
                htmlContent: ''
            },
            status: 'inactive',
            connectionStatus: { status: 'inactive', message: 'Not running', lastUpdate: '' }
        }));

    const allWatchers = [...activeWatchers, ...savedWatchers];

    res.json({ watchers: allWatchers, wechatConfig });
});

// 配置企业微信群key - 需要身份验证
app.post('/api/wechat/config', requireAuth, (req, res) => {
    const { webhookKey } = req.body;
    if (!webhookKey) {
        return res.status(400).json({ error: 'Webhook key is required' });
    }

    wechatConfig.webhookKey = webhookKey;
    saveWeChatConfig(wechatConfig);
    res.json({ message: 'WeChat webhook key updated successfully' });
});

// 获取企业微信配置 - 需要身份验证
app.get('/api/wechat/config', requireAuth, (req, res) => {
    res.json(wechatConfig);
});

// 邮件回调处理接口 - 不需要身份验证（外部回调）
app.post('/api/mail/callback', async (req, res) => {
    try {
        const { account, from, subject, to } = req.body;

        console.log(`Received mail callback for ${account}`);

        // 发送企业微信通知
        await sendToWeChat(wechatConfig.webhookKey, subject, from, to);

        res.json({ message: 'Callback processed successfully' });
    } catch (error) {
        console.error('Error processing mail callback:', error);
        res.status(500).json({ error: 'Failed to process callback' });
    }
});

// 重启监听器函数
function startWatching(email, password, imapConfig, callback, autoReply) {
    const imap = new Imap({
        user: email,
        password,
        host: imapConfig.host,
        port: imapConfig.port,
        tls: imapConfig.tls,
        // 添加超时和连接配置
        connTimeout: 60000, // 连接超时 60秒
        authTimeout: 30000, // 认证超时 30秒
        keepalive: true,
        keepaliveInterval: 10000, // 心跳间隔 10秒
        // 调试模式
        debug: console.log
    });

    let reconnectAttempts = 0;
    const maxReconnectAttempts = 3;
    const reconnectDelay = 5000; // 5秒后重连

    function connect() {
        console.log(`[${email}] Attempting to connect to IMAP server...`);
        console.log(`[${email}] Server: ${imapConfig.host}:${imapConfig.port}, TLS: ${imapConfig.tls}`);
        updateWatcherStatus(email, 'connecting', 'Connecting to IMAP server...');

        imap.connect();
    }

    function reconnect() {
        if (reconnectAttempts < maxReconnectAttempts) {
            reconnectAttempts++;
            console.log(`[${email}] Attempting to reconnect (${reconnectAttempts}/${maxReconnectAttempts}) in ${reconnectDelay / 1000} seconds...`);
            updateWatcherStatus(email, 'connecting', `Reconnecting... (${reconnectAttempts}/${maxReconnectAttempts})`);
            setTimeout(() => {
                connect();
            }, reconnectDelay);
        } else {
            console.error(`[${email}] Max reconnection attempts reached. Stopping watcher.`);
            updateWatcherStatus(email, 'error', 'Max reconnection attempts reached');
            // 从监听器列表中移除失败的连接
            if (watchers[email]) {
                delete watchers[email];
                delete watcherStatus[email];
                saveWatchersConfig();
            }
        }
    }

    imap.once('ready', () => {
        console.log(`[${email}] IMAP connected successfully`);
        reconnectAttempts = 0; // 重置重连计数
        updateWatcherStatus(email, 'connected', 'Successfully connected to IMAP server');

        imap.openBox('INBOX', false, (err, box) => {
            if (err) {
                console.error(`[${email}] openBox error:`, err);
                updateWatcherStatus(email, 'error', `Failed to open INBOX: ${err.message}`);
                return;
            }

            console.log(`[${email}] INBOX opened successfully`);
            updateWatcherStatus(email, 'connected', 'Monitoring INBOX for new messages');

            imap.on('mail', () => {
                console.log(`[${email}] New mail detected`);
                updateWatcherStatus(email, 'connected', 'Processing new mail...');
                imap.search(['UNSEEN'], (err, results) => {
                    if (err) {
                        console.error(`[${email}] Search error:`, err);
                        updateWatcherStatus(email, 'error', `Search error: ${err.message}`);
                        return;
                    }
                    if (!results || results.length === 0) {
                        console.log(`[${email}] No new messages found`);
                        updateWatcherStatus(email, 'connected', 'Monitoring INBOX for new messages');
                        return;
                    }

                    console.log(`[${email}] Found ${results.length} new message(s), processing only the latest one`);
                    updateWatcherStatus(email, 'connected', `Processing latest message`);

                    // 只处理最新的一封邮件（数组中的最后一个）
                    const latestMessageId = results[results.length - 1];
                    const f = imap.fetch([latestMessageId], { bodies: '' });

                    f.on('message', msg => {
                        let mailBuffer = '';
                        msg.on('body', stream => {
                            stream.on('data', chunk => mailBuffer += chunk.toString('utf8'));
                        });
                        msg.once('end', async () => {
                            try {
                                const parsed = await simpleParser(mailBuffer);
                                const from = parsed.from?.text || '';
                                const subject = parsed.subject || '';
                                const text = parsed.text || '';
                                const html = parsed.html || '';
                                const attachments = parsed.attachments || [];
                                const links = extractLinks(html);
                                const date = parsed.date;
                                const to = parsed.to?.text || '';
                                const cc = parsed.cc?.text || '';
                                const bcc = parsed.bcc?.text || '';

                                console.log(`[${email}] Processing latest mail: ${subject}`);

                                // 检查是否系统邮箱
                                if (from.includes('@mail.nodepro8.com') || subject == 'Undelivered Mail Returned to Sender') {
                                    console.log(`系统邮件，跳过自动回复`);
                                    return;
                                }

                                // 检查并发送自动回复
                                if (autoReply && autoReply.enabled) {
                                    console.log(`[${email}] Auto reply is enabled, sending reply...`);
                                    const replyResult = await sendAutoReply(
                                        email,
                                        password,
                                        imapConfig.host,
                                        imapConfig.port,
                                        imapConfig.tls,
                                        autoReply,
                                        {
                                            from: from,
                                            subject: subject,
                                            messageId: parsed.messageId,
                                            references: parsed.references
                                        }
                                    );

                                    if (replyResult.success && !replyResult.skipped) {
                                        console.log(`[${email}] Auto reply sent successfully`);
                                    } else if (replyResult.error) {
                                        console.error(`[${email}] Auto reply failed: ${replyResult.error}`);
                                    }
                                }

                                // 如果配置了回调地址，发送到回调地址（回调地址会处理企业微信通知）
                                if (callback) {
                                    console.log(`[${email}] Forwarding mail to callback`);
                                    try {
                                        await axios.post(callback, {
                                            account: email,
                                            from,
                                            subject,
                                            text,
                                            html,
                                            attachments: attachments.map(att => ({
                                                filename: att.filename,
                                                contentType: att.contentType,
                                                size: att.size
                                            })),
                                            links,
                                            date,
                                            to,
                                            cc,
                                            bcc,
                                            messageId: parsed.messageId,
                                            inReplyTo: parsed.inReplyTo,
                                            references: parsed.references
                                        });
                                        console.log(`[${email}] Callback success`);
                                    } catch (err) {
                                        console.error(`[${email}] Callback error:`, err.message);
                                    }
                                }
                                updateWatcherStatus(email, 'connected', 'Monitoring INBOX for new messages');
                            } catch (err) {
                                console.error(`[${email}] Parse error:`, err);
                                updateWatcherStatus(email, 'error', `Mail parse error: ${err.message}`);
                            }
                        });
                    });

                    f.once('error', err => {
                        console.error(`[${email}] Fetch error:`, err);
                        updateWatcherStatus(email, 'error', `Fetch error: ${err.message}`);
                    });
                });
            });
        });
    });

    imap.once('error', err => {
        console.error(`[${email}] IMAP error:`, err);

        // 根据错误类型决定是否重连
        if (err.source === 'timeout-auth') {
            console.error(`[${email}] Authentication timeout. Please check credentials and server settings.`);
            updateWatcherStatus(email, 'error', 'Authentication timeout - check credentials');
        } else if (err.source === 'timeout') {
            console.error(`[${email}] Connection timeout. Attempting to reconnect...`);
            updateWatcherStatus(email, 'error', 'Connection timeout - attempting reconnect');
            reconnect();
            return;
        } else if (err.code === 'ECONNREFUSED') {
            console.error(`[${email}] Connection refused. Please check server address and port.`);
            updateWatcherStatus(email, 'error', 'Connection refused - check server/port');
        } else if (err.code === 'ENOTFOUND') {
            console.error(`[${email}] Server not found. Please check server address.`);
            updateWatcherStatus(email, 'error', 'Server not found - check address');
        } else {
            console.error(`[${email}] Unexpected error:`, err);
            updateWatcherStatus(email, 'error', `Unexpected error: ${err.message}`);
        }

        // 对于认证错误，不进行重连，直接移除监听器
        if (err.source === 'timeout-auth' || err.code === 'ECONNREFUSED' || err.code === 'ENOTFOUND') {
            console.log(`[${email}] Removing watcher due to persistent error`);
            if (watchers[email]) {
                delete watchers[email];
                delete watcherStatus[email];
                saveWatchersConfig();
            }
        } else {
            reconnect();
        }
    });

    imap.once('end', () => {
        console.log(`[${email}] IMAP connection ended`);
        updateWatcherStatus(email, 'disconnected', 'Connection ended');
        // 如果不是主动断开，尝试重连
        if (watchers[email]) {
            console.log(`[${email}] Connection ended unexpectedly, attempting to reconnect...`);
            reconnect();
        }
    });

    // 启动连接
    connect();
    return imap;
}

// 添加监听 - 需要身份验证
app.post('/add', requireAuth, (req, res) => {
    const { email, password, host, port, tls, callback, autoReply } = req.body;
    if (watchers[email]) {
        return res.status(400).json({ error: 'Already watching this email' });
    }

    const imapConfig = {
        host: host || 'mail.nodepro8.com',
        port: port || 993,
        tls: tls !== false  // 默认 true
    };

    const autoReplyConfig = autoReply || {
        enabled: false,
        subjectPrefix: 'Re: ',
        textContent: '感谢您的邮件，我已收到并会尽快回复。',
        htmlContent: ''
    };

    try {
        const imap = startWatching(email, password, imapConfig, callback, autoReplyConfig);

        // 保存监听器配置
        watchers[email] = {
            imap,
            callback,
            host: imapConfig.host,
            port: imapConfig.port,
            tls: imapConfig.tls,
            autoReply: autoReplyConfig
        };

        // 保存到文件
        saveWatchersConfig();

        res.json({ message: `Started watching ${email}` });
    } catch (error) {
        console.error(`Failed to start watching ${email}:`, error);
        res.status(500).json({ error: 'Failed to start watching email' });
    }
});

// 移除监听 - 需要身份验证
app.post('/remove', requireAuth, (req, res) => {
    const { email } = req.body;
    const watcher = watchers[email];
    if (!watcher) {
        return res.status(400).json({ error: 'Not watching this email' });
    }
    watcher.imap.end();
    delete watchers[email];

    // 保存到文件
    saveWatchersConfig();

    res.json({ message: `Stopped watching ${email}` });
});

// 更新监听配置 - 需要身份验证
app.post('/update', requireAuth, (req, res) => {
    const { email, callback, autoReply } = req.body;
    const watcher = watchers[email];
    if (!watcher) {
        return res.status(400).json({ error: 'Not watching this email' });
    }

    // 更新回调地址和自动回复配置
    if (callback !== undefined) {
        watchers[email].callback = callback;
    }
    if (autoReply !== undefined) {
        watchers[email].autoReply = autoReply;
    }

    // 保存到文件
    saveWatchersConfig();

    res.json({ message: `Updated configuration for ${email}` });
});

// 重启监听器接口 - 需要身份验证
app.post('/restart', requireAuth, (req, res) => {
    const { email, password } = req.body;

    if (!email || !password) {
        return res.status(400).json({ error: 'Email and password are required' });
    }

    const savedConfig = savedWatchersConfig[email];
    if (!savedConfig) {
        return res.status(400).json({ error: 'No saved configuration found for this email' });
    }

    if (watchers[email]) {
        return res.status(400).json({ error: 'Email is already being watched' });
    }

    try {
        const imap = startWatching(email, password, savedConfig, savedConfig.callback, savedConfig.autoReply);

        watchers[email] = {
            imap,
            callback: savedConfig.callback,
            host: savedConfig.host,
            port: savedConfig.port,
            tls: savedConfig.tls,
            autoReply: savedConfig.autoReply || {
                enabled: false,
                subjectPrefix: 'Re: ',
                textContent: '感谢您的邮件，我已收到并会尽快回复。',
                htmlContent: ''
            }
        };

        res.json({ message: `Restarted watching ${email}` });
    } catch (error) {
        console.error(`Failed to restart watching ${email}:`, error);
        res.status(500).json({ error: 'Failed to restart watching email' });
    }
});

// 启动服务
const PORT = 3001;
app.listen(PORT, () => {
    console.log(`Server started on port ${PORT}`);
    console.log(`Web interface available at http://localhost:${PORT}`);
    console.log(`Mail callback endpoint: http://localhost:${PORT}/api/mail/callback`);
    console.log(`Data directory: ${DATA_DIR}`);
    console.log(`Admin password: ${ADMIN_PASSWORD}`);
});